package com.quanyan.common.utils;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class CommonUtils {

    public final static String[] CHINESE_DIGIST_LETTER = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};

    public final static String[] ALL_LETTER = {
            "a", "b", "c", "d", "e", "f", "g",
            "h", "i", "j", "k", "l", "m", "n",
            "o", "p", "q", "r", "s", "t", "u",
            "v", "w", "x", "y", "z"
    };

    public final static String[] ALL_DIGIT_LETTER = {
            "0", "1", "2", "3", "4", "5", "6",
            "7", "8", "9",
            "a", "b", "c", "d", "e", "f", "g",
            "h", "i", "j", "k", "l", "m", "n",
            "o", "p", "q", "r", "s", "t", "u",
            "v", "w", "x", "y", "z"
    };

    public static boolean validName(String name)
    {
        if(name.replaceAll("[^0-9a-zA-Z\\u4e00-\\u9fa5]", "").length() == name.length())
        {
            return true;
        }
        return false;
    }

    public static int randomInt(int min, int max) {
        Random random = new Random();
        int s = random.nextInt(max) % (max - min + 1) + min;
        return s;
    }

    public static String replaceSpecialCharactor(String content) {
        return content.replaceAll("[`~!@#\\$%^\\&\\*()_+-,\\.<>?/\"\\'\\[\\]\\{\\}]", "");
    }


    /**
     * 加密
     *
     * @param content  需要加密的内容
     * @param password 加密密码
     */
    public static byte[] encrypt(String content, String password) throws NoSuchAlgorithmException {
        try {
            /*
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            */
            SecretKeySpec key = new SecretKeySpec(parseHexStr2Byte("296BD8C9DA72B12EC22F1347B7B11C04"), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(byteContent);
            return result; // 加密
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密
     *
     * @param content  待解密内容
     * @param password 解密密钥
     */
    public static byte[] decrypt(byte[] content, String password) {
        try {

            SecretKeySpec key = new SecretKeySpec(parseHexStr2Byte("296BD8C9DA72B12EC22F1347B7B11C04"), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器

            /*
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            */

            cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(content);
            return result; // 加密
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将二进制转换成16进制
     */
    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将16进制转换为二进制
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    public static void main(String args[]) throws NoSuchAlgorithmException {

//        System.out.println(getOrderNo());
//        System.out.println(getRandomString());


        // System.out.println(stripTags("<a href=''>test</a>"));
        /*
        String password = "AIPUTTCOM5606";
        //加密
        long stime=System.currentTimeMillis();
        String content="{\"baseInfo\":{\"w\":720,\"activity\":\"1\",\"phonetype\":\"google||Galaxy Nexus\",\"fid\":\"10001\",\"netType\":2,\"dsn\":\"54E0F5258D3615A534DD49C508A94013\",\"h\":1184,\"sysVersion\":\"4.2.2\",\"version\":\"1.2.0.001\"}}";

        System.out.println("加密前：" + content);
        byte[] encryptResult = CommonUtils.encrypt(content, password);
        String encryptResultStr = CommonUtils.parseByte2HexStr(encryptResult);
        System.out.println("加密后：" + encryptResultStr);
        //解密
        byte[] decryptFrom = CommonUtils.parseHexStr2Byte(encryptResultStr);
        byte[] decryptResult = CommonUtils.decrypt(decryptFrom, password);
        System.out.println("解密后：" + new String(decryptResult));
        */

//        System.out.println(generateBusinessOrderNo("C",232323));
//        System.out.println(digistToChinese(421823549));
//        System.out.println(generateQcode(999999999));
//        System.out.println(generateQcode(999));

        //  System.out.println(replaceSpecialCharactor("骑行只要2231分钱11$#$^&*ghchfhdhdd"));


        System.out.println(generateRefundNo("R"));

    }

    public static String stripTags(String str) {
        String matchScore = str;

        Pattern p = Pattern.compile("<[^>]+>([^<]*)</[^>]+>");
        Matcher m = p.matcher(matchScore);
        while (m.find()) {
            matchScore = matchScore.replaceFirst("<[^>]+>([^<]*)</[^>]+>", m.group(1).toString());
        }
        System.out.println(matchScore);
        return matchScore;

    }

    public static String tipDate(Date srcDate) {
        Date now = new Date();
        StringBuffer sb = new StringBuffer();
        Date date = srcDate;
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);


        sb.append("");
        if (day > 0)
            sb.append(day + "天");
        if (hour > 0)
            sb.append(hour + "小时");
        if (min > 0)
            sb.append(min + "分");
        sb.append(s + "秒 前");

        return sb.toString();

    }

    public static boolean isIos(String userAgent) {
        if (userAgent.toLowerCase().indexOf("android") > 0) {
            return false;
        }
        return userAgent.toLowerCase().indexOf("iphone") > 0 ||
                userAgent.toLowerCase().indexOf("ipad") > 0 ||
                userAgent.toLowerCase().indexOf("mac ") > 0 ||
                userAgent.toLowerCase().indexOf("ios") > 0;
    }


    /**
     * 生成订单号码的规则.
     */
    public static String generateOrderNo(Integer uid) {
        String userString = zeroFill(uid % 1000000 + "", 6);
//        String random = RandomStringUtils.randomNumeric(2);
        String random = StringUtils.leftPad(ThreadLocalRandom.current().nextInt(100)+"", 2, "0");
        return getSysRunMillis() + userString + random;//系统运行第几年 + 该年第几天 + 当天秒数     + 该秒毫秒数      +  用户ID后四位 + 随机数
    }

    /**
     * 生成退款单号的规则.
     */
    public static String generateRefundNo(String  bussinessCode) {
 
        return bussinessCode+getSysRunMillis();//业务类型编码+系统运行第几年 + 该年第几天 + 当天秒数     + 该秒毫秒数       
    }

    /**
     * 业务系统订单号的规则.
     */
    public static String generateBusinessOrderNo(String businessCode, Integer uid) {
        return businessCode + generateOrderNo(uid);
    }

    /**
     * 跑步骑行唯一token生成规则.
     */
    public static String generateRunRideToken(String businessCode, Integer uid) {
        return businessCode + generateToken(uid);
    }

    public static String generateToken(Integer uid) {
        String userString = zeroFill(uid % 1000000 + "", 6);
        String random = RandomStringUtils.randomNumeric(2);
        return getSysRunMillis() + userString + random;//系统运行第几年 + 该年第几天 + 当天秒数     + 该秒毫秒数      +  用户ID后四位 + 随机数
    }
    /**
     * 12~13位 + 6位 + 3位
     */
    public static String getSysRunMillis() {
        DateTime dateTime = DateTime.now();
        int runYear = dateTime.getYear() - 2015 + 1;
        String secondOfDay = zeroFill(dateTime.secondOfDay().getAsString(), 5);
        String dayOfYear = zeroFill(dateTime.getDayOfYear() + "", 3);
        String millisOfSecond = zeroFill(dateTime.millisOfSecond().getAsString(), 3);
        return runYear + dayOfYear + secondOfDay + millisOfSecond;
    }

    public static String zeroFill(String str, int length) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < length - str.length(); i++) {
            buffer.append("0");
        }
        return buffer.toString() + str;
    }


    /**
     * 将数字转换为汉字
     *
     * @param i 任意长数字
     * @return 汉子字符串
     */
    public static String digistToChinese(int i) {
        StringBuffer buffer = new StringBuffer();
        while (i != 0) {
            buffer.insert(0, CHINESE_DIGIST_LETTER[i % 10]);
            i = i / 10;
        }
        return buffer.toString();
    }


    /**
     * 获取32位随机字符串
     */
    public static String getRandomString() {
        StringBuffer buffer = new StringBuffer();
        int count = ALL_DIGIT_LETTER.length;
        for (int i = 0; i < 32; i++) {
            buffer.append(ALL_DIGIT_LETTER[randomInt(0, count - 1)]);
        }
        return buffer.toString().toUpperCase();
    }


    public static String generateQcode(int i) {
        String result = zeroFill(i + "", 4);
        if (result.length() <= 4) {
            DateTime dateTime = DateTime.now();
            return dateTime.getYear() + result;
        } else {
            return zeroFill(result, 8);
        }
    }

    /**
     * 生成业务流水号
     * @param bizId
     * @return
     */
    public static String generateNo(Integer bizId) {
        String bizString = zeroFill(bizId % 1000000 + "", 6);
        String date = new SimpleDateFormat("yyyyMMdd").format(new java.util.Date());
        String time = new SimpleDateFormat("HHmmss").format(new java.util.Date());
        return date + bizString +  time  + RandomStringUtils.randomNumeric(4);
    }

    /**
     * 生成场馆销售计划id
     * @param placeUnitId
     * @param date
     * @param startTime
     * @return
     */
    public static String createSaleID(Integer placeUnitId, Date date, Date startTime, Date endTime) {
        //md5会冲突，先用UUID

        String str_date = DateTimeUtils.convertDate2String("yyyy-MM-dd", date);
        String str_startTime = DateTimeUtils.convertDate2String("HH:mm:ss", startTime);
        StringBuilder sb = new StringBuilder();
        sb.append(placeUnitId).append(str_date).append(str_startTime);
        if (null != endTime){
            String str_endTime = DateTimeUtils.convertDate2String("HH:mm:ss", endTime);
            sb.append(str_endTime);
        }
        return MD5Utils.MD5Encode(sb.toString());

//        UUID randomUUID = UUID.randomUUID();
//        String uuid = randomUUID.toString().replaceAll("-", "");
//        StringBuffer bf = new StringBuffer();
//        bf.append(uuid);
//        return bf.toString().toLowerCase();
    }

    public static Double mathUtil(List<Double> doubles) {
        Double lowest = 0.00;
        for (int i = 0; i < doubles.size(); i++) {
            if (i == 0) {
                lowest = doubles.get(i);
            } else {
                if (doubles.get(i) < lowest) {
                    lowest = doubles.get(i);
                }
            }
        }
        return lowest;
    }
}
